
# 1. 在 Web 开发中，用装饰器将 URL 路径与处理函数绑定（类似 Flask 框架）。
class Router:
    def __init__(self):
        self.routes = {}

    def route(self, path):
        def decorator(func):
            self.routes[path] = func
            # 这里其实没有改写，只是对func进行了添加
            return func
        return decorator

router = Router()

@router.route("/home")
def home():
    return "Welcome to Home Page!"

@router.route("/about")
def about():
    return "About Us"

# 模拟请求处理
def handle_request(path):
    handler = router.routes.get(path)
    return handler() if handler else "404 Not Found"

print(handle_request("/home"))  # 输出: Welcome to Home Page!


'''  -----------------------------------------------------------------------------------'''
#  2
from functools import wraps

def require_role(role):
    def decorator(func):
        @wraps(func)
        def wrapper(user, *args, **kwargs):
            if user.get("role") != role:
                raise PermissionError(f"需要 {role} 权限")
            return func(user, *args, **kwargs)
        return wrapper
    return decorator

@require_role("admin")
def delete_user(user, user_id):
    print(f"用户 {user['name']} 删除了ID为 {user_id} 的用户")

# 测试
admin_user = {"name": "Alice", "role": "admin"}
normal_user = {"name": "Bob", "role": "user"}

delete_user(admin_user, 123)  # 正常执行
# delete_user(normal_user, 123)  # 抛出 PermissionError

'''  -----------------------------------------------------------------------------------'''
#  3 确保一个类只有一个实例


class only_one:
    def __init__(self):
        self.times = 0
    
    def only_one(self,func):
        def wrapper(*args,**kwargs):
            if self.times >= 1:
                raise Exception
            self.times += 1
            func(*args,**kwargs)
        return wrapper

# @only_one.only_one
# class example1:
#     def __init__(self):
#         pass
    #下面是deepseek写的
def singleton(cls):
    instances = {}
    def wrapper(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return wrapper

@singleton
class DatabaseConnection:
    def __init__(self):
        print("创建数据库连接")

conn1 = DatabaseConnection()  # 输出: 创建数据库连接
conn2 = DatabaseConnection()  # 无输出
print(conn1 is conn2)  # True
'''  -----------------------------------------------------------------------------------'''
#  4 函数调用日志增强
#  自动记录函数的输入，输出，异常
import logging
import functools
def zengqiang(func):
    @wraps(func) 
    def wrapper(*args,**kwargs):
        #记录传入的参数

        try:
            
            rs = func(*args,**kwargs)
            #记录结果rs
            return rs
        except Exception as e:
            #记录异常
            logging.error(f"{func.__name__}抛出异常：{str(e)}")
            
            
    return wrapper
'''  -----------------------------------------------------------------------------------'''
#  5. pytest中数据驱动用到的
# @parametrize('para1,para2,para3',[(元组1)，(元组2)]
# def test_a(self,para1,para2,para3)
canshu = []
def parametrize(para1,para2):
    def decorator(func):
        para_name_list = para1.split(',')
        # 排序
        for i in para2:
            z = zip(para_name_list,i)
            for j in z:
                # j应该是一个 元组 
                print(j)
            # 读取func的参数的排序 ，对 参数排序

        # 不排序了 直接简化 
        canshu = para2

        def wrapper(*args,**kwargs):
            for i in canshu:
                func(*i)
        return wrapper
    
    return decorator

@parametrize('para2,para1,para3',[(1,2,3),('a','b','c')])
def test_a(para1,para2,para3):
    print(f'执行了test_a方法，参数是{para1},{para2},{para3}')

test_a()

'''  -----------------------------------------------------------------------------------'''
# 5 游戏技能冷却装饰器
# 
import time

def cooldown(second):

    def decorator(func):
        time_to = {}
        time_to[func] = 0  # 只会执行一次
        def wrapper(*args,**kwargs):
            now = time.time()
            nonlocal time_to
            if time_to[func] == 0:
                #释放
                func()
                time_to[func] = now
            elif now - time_to[func] >= second:
                func()
                time_to[func] = now
            else:
                print('技能还未冷却')
        return wrapper
    return decorator



@cooldown(5)
def fireball():
    print('火球术释放')

fireball()
time.sleep(2)
fireball()
time.sleep(2.9)
fireball()
time.sleep(0.1)
fireball()

# import time

# def cooldown(delay):
#     last_called = 0
#     def decorator(func):
#         def wrapper(*args, **kwargs):
#             nonlocal last_called
#             current = time.time()
#             if current - last_called < delay:
#                 raise Exception(f"技能冷却中，剩余时间: {delay - (current - last_called):.1f}秒")
#             last_called = current
#             return func(*args, **kwargs)
#         return wrapper
#     return decorator

# @cooldown(5)  # 5秒冷却
# def fireball():
#     print("火球术释放！")

# # 测试
# fireball()
# time.sleep(2)
# fireball()
# time.sleep(2.9)
# fireball()
# time.sleep(0.1)
# fireball()


'''  -----------------------------------------------------------------------------------'''
# 6 用装饰器处理yaml文件中占位符的替换
# 